#include <arpa/inet.h> //inet_ntoa header file
#include <errno.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h> //perror and exit header file
#include <string.h> //bzero
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "simplesock.h"

#define PORT 10008
#define BACKLOG 2
#define MAXDATASIZE 1000

void process_cli(int connected, sockaddr_in client);

void sig_chld(int signo)
{
    pid_t pid;
    int stat;
    while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
        printf("child %d terminated!\n", pid);
    }
    return;
}

int main()
{
    int listenfd, connectfd;
    pid_t pid;
    ServerSock mysock;
    listenfd = mysock.CreateServer(PORT);
    signal(SIGCHLD, sig_chld);
    if (listenfd < 0) {
        printf("create server sock error : %s", mysock.GetErrorInfo());
        exit(1);
    }
    struct sockaddr_in client;
    while (1) {
        connectfd = mysock.Accept(100000, (struct sockaddr *)&client);
        if (0 >= connectfd) {
            printf("err info = %s, conneted fd = %d\n", mysock.GetErrorInfo(), connectfd);
            continue;
        }

        if (0 < (pid = fork())) {
            close(connectfd);
            continue;
        } else if (0 == pid) {
            close(listenfd);
            process_cli(connectfd, client);
            exit(0);
        } else {
            printf("fork error \n");
            exit(0);
        }
    }
    close(listenfd);
}

void process_cli(int connectfd, sockaddr_in client)
{
    int num;
    char recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], cli_name[MAXDATASIZE];
    printf("you got a connect from %s \n", inet_ntoa(client.sin_addr));
    num = recv(connectfd, cli_name, MAXDATASIZE, 0);
    if (0 == num) {
        close(connectfd);
        printf("client disconnected. \n");
        return;
    }
    cli_name[num - 1] = '\0';

    while (0 == (num = recv(connectfd, recvbuf, MAXDATASIZE, 0))) {
        if (num < 0) {
            printf("error info is: %s\n", strerror(errno));
            close(connectfd);
            printf("client disconnected. \n");
            return;
        }
        recvbuf[num] = '\0';
        printf("reveived client(%s) message: %s, num=%d, \n", cli_name, recvbuf, num);
        for (int i = 0; i < num - 1; i++) {
            sendbuf[i] = recvbuf[num - i - 2];
        }
        sendbuf[num - 1] = '\0';

        send(connectfd, sendbuf, strlen(sendbuf), 0);
        printf("send recive data : %s, handl=%d, length=%d\n", sendbuf, connectfd,
               (int)strlen(sendbuf));
    }
    close(connectfd);
}
